<template>
    <div class="source">
        <div class="source-left">
            <!-- <div class="source-top">
                <span></span>
                <el-button-group>
                    <el-button type="primary" size="mini" icon="el-icon-plus" @click="sourceAdd">添加</el-button>
                </el-button-group>
            </div> -->
            <ul class="source-list">
                <li class="source-item"
                    :class="{
                        'is-active': model && item.id === model.id
                    }"
                    v-for="(item, index) in sourceList"
                    :key="index"
                    @click.stop="handleSourceItem(item)"
                >
                    <el-row :gutter="10" type="flex" style="align-item: center; width: 100%;">
                        <el-col :span="4" style="text-align: center;">
                            <span class="text collor-success">{{item.method}}</span>
                        </el-col>
                        <el-col :span="14">
                            <el-tooltip effect="dark" :content="item.name" placement="top">
                                <span class="text">{{item.name}}</span>
                            </el-tooltip>
                        </el-col>
                        <el-col :span="6" style="text-align: center;">
                            <el-button type="text" size="mini" icon="el-icon-document-copy" @click.stop="sourceItemCopy(item, index)"></el-button>
                            <el-divider direction="vertical"></el-divider>
                            <el-popconfirm
                                v-if="!model || model.id !== item.id"
                                title="确定删除该数据源？"
                                @confirm="sourceItemDelete(item, index)"
                            >
                                <el-button type="text" slot="reference" size="mini" icon="el-icon-delete" @click.stop></el-button>
                            </el-popconfirm>
                        </el-col>
                    </el-row>
                </li>
            </ul>
        </div>
        <div class="source-right">
            <div class="source-top">
                <span></span>
                <el-button-group>
                    <el-button v-if="model" size="mini" icon="el-icon-finished" :loading="httpTestLoading" @click="httpTest">请求测试</el-button>
                    <el-button v-if="!model" type="primary" size="mini" icon="el-icon-plus" @click="sourceAdd">添加</el-button>
                    <el-button v-if="model" type="primary" size="mini" icon="el-icon-folder" @click="sourceSave">保存</el-button>
                </el-button-group>
            </div>
            <div class="source-form">
                <div v-if="model" class="source-form-clear">
                    <el-button type="text" size="mini" icon="el-icon-close" @click.stop="formClear"></el-button>
                </div>
                <VoSchemaForm ref="sf" v-if="model" :model="model" :schema="schema" :rules="rules" @change="formChange">
                    <template #headers="{ model }">
                        <ul v-if="model.headers">
                            <li class="source-form-item" v-for="(item, index) in model.headers" :key="index">
                                <el-row :gutter="20" type="flex" style="width: 100%;">
                                    <el-col :span="8">
                                        <el-input v-model="item.key" placeholder="请输入键" @change="formItemChange" style="width: 100%;"></el-input>
                                    </el-col>
                                    <el-col :span="14">
                                        <el-input v-model="item.value" type="textarea" autosize placeholder="请输入值" @change="formItemChange" style="width: 100%;"></el-input>
                                    </el-col>
                                    <el-col :span="2">
                                        <el-button type="text" size="mini" icon="el-icon-delete" @click="sourceHeadersDelete(item, index)"></el-button>
                                    </el-col>
                                </el-row>
                            </li>
                        </ul>
                        <el-button type="text" icon="el-icon-plus" @click="headersAdd">添加</el-button>
                    </template>
                    <template #params>
                        <ul v-if="model.params">
                            <li class="source-form-item" v-for="(item, index) in model.params" :key="index">
                                <el-row :gutter="20" type="flex" style="width: 100%;">
                                    <el-col :span="8">
                                        <el-input v-model="item.key" placeholder="请输入键" @change="formItemChange" style="width: 100%;"></el-input>
                                    </el-col>
                                    <el-col :span="14">
                                        <el-input v-model="item.value" type="textarea" autosize placeholder="请输入值" @change="formItemChange" style="width: 100%;"></el-input>
                                    </el-col>
                                    <el-col :span="2">
                                        <el-button type="text" size="mini" icon="el-icon-delete" @click="sourceParamsDelete(item, index)"></el-button>
                                    </el-col>
                                </el-row>
                            </li>
                        </ul>
                        <el-button type="text" icon="el-icon-plus" @click="paramsAdd">添加</el-button>
                    </template>

                    <template #footer>
                        <span></span>
                    </template>
                </VoSchemaForm>
                <div class="empty" v-if="!model">
                    请点击 <el-button type="text" @click="sourceAdd">添加</el-button> 新增数据源 或 点击左侧数据源编辑
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import { mapState } from 'vuex'
import { clone } from '@/utils/clone'
import api from '@/http'

export default {
    data() {
        return {
            sourceList: [],
            isChange: false,
            model: null,
            schema: {
                properties: {
                    name: {
                        label: '数据源名称',
                        widget: 'input',
                        ui: {
                            placeholder: '请输入数据源名称',
                            maxlength: 100
                        }
                    },
                    url: {
                        label: '请求地址',
                        widget: 'input',
                        ui: {
                            placeholder: '请输入请求地址',
                            type: 'textarea',
                            maxlength: 9999
                        }
                    },
                    method: {
                        label: '请求方法',
                        widget: 'radioButton',
                        enum: [
                            { label: 'GET', value: 'GET' },
                            { label: 'POST', value: 'POST' },
                            { label: 'PUT', value: 'PUT' },
                            { label: 'DELETE', value: 'DELETE' }
                        ]
                    },
                    headers: {
                        label: '请求头部',
                        widget: 'custom'
                    },
                    params: {
                        label: '请求参数',
                        widget: 'custom'
                    }
                },
                ui: {
                    labelWidth: 100,
                    labelPosition: 'right'
                }
            },
            rules: {
                name: [
                    { required: true, message: '请输入数据源名称', trigger: 'blur' }
                ],
                url: [
                    { required: true, message: '请输入请求地址', trigger: 'blur' }
                ],
                method: [
                    { required: true, message: '请选择请求方法', trigger: 'blur' }
                ]
            },
            httpTestLoading: false
        }
    },
    computed: {
        ...mapState({
            formSource: state => state.schemaSource.formSource
        })
    },
    created() {
        this.sourceList = clone(this.formSource)
    },
    methods: {
        formItemChange() {
            this.isChange = true
        },
        formChange() {
            this.isChange = true
        },
        sourceAdd() {
            this.isChange = false;
            this.model = {
                name: '新增数据',
                url: '',
                method: 'GET',
                headers: [],
                params: []
            }
        },
        headersAdd() {
            if (!this.model.headers) {
                this.$set(this.model, 'headers', [])
            }
            this.model.headers.push({ key: '', value: '' })
            this.isChange = true
        },
        sourceHeadersDelete(item, index) {
            this.model.headers.splice(index, 1)
            this.isChange = true
        },
        paramsAdd() {
            if (!this.model.params) {
                this.$set(this.model, 'params', [])
            }
            this.model.params.push({ key: '', value: '' })
            this.isChange = true
        },
        sourceParamsDelete(item, index) {
            this.model.params.splice(index, 1)
            this.isChange = true
        },
        handleSourceItem(item) {
            if (this.isChange) {
                this.$confirm('当前数据源未保存，是否放弃保存？', '提示', {
                    distinguishCancelAndClose: true,
                    confirmButtonText: '放弃',
                    cancelButtonText: '取消'
                }).then(() => {
                    this.model = clone(item)
                    this.isChange = false;
                }).catch(_ => {});
            } else {
                this.model = clone(item)
            }
        },
        sourceItemCopy(item, index) {
            const data = clone({
                ...item,
                name: `${item.name}-复制`
            })
            delete data.id
            if (this.isChange) {
                this.$confirm('当前数据源未保存，是否放弃保存？', '提示', {
                    distinguishCancelAndClose: true,
                    confirmButtonText: '放弃',
                    cancelButtonText: '取消'
                }).then(() => {
                    this.model = data
                    this.isChange = false;
                }).catch(_ => {});
            } else {
                this.model = data
            }
        },
        sourceItemDelete(item, index) {
            if (this.model && this.model.id === item.id) {
                this.model = null
            }
            this.sourceList.splice(index, 1)
        },
        sourceSave() {
            if (this.$refs.sf) {
                this.$refs.sf.validate((boo) => {
                    console.log(boo);
                    if (boo) {
                        this.$message.success('保存成功')
                    }
                })
            }
        },
        formClear() {
            if (this.isChange) {
                this.$confirm('当前数据源未保存，是否放弃保存？', '提示', {
                    distinguishCancelAndClose: true,
                    confirmButtonText: '放弃',
                    cancelButtonText: '取消'
                }).then(() => {
                    this.model = null
                    this.isChange = false;
                }).catch(_ => {});
            } else {
                this.model = null
            }
        },
        handleParams(params) {
            const p = {}
            if (Array.isArray(params)) {
                params.forEach(e => {
                    if (e.key && e.value) {
                        p[e.key] = e.value
                    }
                })
            }
            return p
        },
        // 测试
        httpTest() {
            if (this.$refs.sf && this.model) {
                this.$refs.sf.validate((boo) => {
                    if (boo) {
                        this.httpTestLoading = true;
                        const { method, url, params } = this.model
                        api.ajax(method, url, this.handleParams(params)).then(res => {
                            this.$message.success('请求成功')
                            console.log(res);
                            this.httpTestLoading = false;
                        }).catch(() => {
                            this.$message.error('请求失败')
                            this.httpTestLoading = false;
                        })
                    }
                })
            }
        }
    }
}
</script>

<style lang="scss" scoped>
.collor-success{
    color: #67C23A;
}
.source{
    display: flex;
    flex-wrap: wrap;
    border: 1px solid #DCDFE6;
    border-radius: 4px;
    .source-top{
        width: 100%;
        box-sizing: border-box;
        padding-bottom: 10px;
        border-bottom: 1px solid #DCDFE6;
        display: flex;
        justify-content: space-between;
    }
    .source-left{
        min-width: 300px;
        width: 300px;
        box-sizing: border-box;
        padding: 10px;
        border-right: 1px solid #DCDFE6;
    }
    .source-right{
        flex: 1;
        box-sizing: border-box;
        padding: 10px;
    }
    .source-list{
        padding-top: 10px;
        height: 636px;
        overflow: auto;
        .source-item{
            box-sizing: border-box;
            border: 1px solid #E4E7ED;
            border-radius: 4px;
            padding: 4px 0 4px 10px;
            cursor: pointer;
            & + .source-item{
                margin-top: 10px;
            }
            &.is-active{
                background: #E4E7ED;
            }
            .text{
                display: block;
                line-height: 28px;
                white-space:nowrap;
                overflow:hidden;
                text-overflow:ellipsis;
            }
        }
    }
    .source-form{
        padding-top: 10px;
        height: 600px;
        position: relative;
        overflow: auto;
        .source-form-item{
            & + .source-form-item{
                margin-top: 8px;
            }
        }
        .source-form-clear{
            margin-top: -10px;
            text-align: right;
        }
    }
    .empty{
        margin-top: 100px;
        text-align: center;
        color: #909399;
    }
}
</style>
